// 观察者模式与回调函数的关系
// 相似之处
// 1.控制反转：两者都实现了控制反转，让被观察对象/被调用函数在特定事件发生时通知观察者/调用回调函数
// 2.解耦：两者都能将事件发生者和事件处理者解耦
// 3.用途：两者都常用于事件处理、异步编程和状态变化通知

// 核心区别
// 1结构复杂度：
//      回调函数通常更简单，直接传递函数指针或函数对象
//      观察者模式更结构化，通常涉及接口定义和类继承
// 2通知对象数量：
//      回调函数通常是一对一关系（一个事件对应一个回调）
//      观察者模式支持一对多关系（一个主题可以有多个观察者）
// 3生命周期管理：
//      观察者模式通常有明确的注册/注销机制
//      回调函数的生命周期管理相对简单，但可能更容易出错
// 4耦合程度：
//      观察者模式中，主题只知道观察者接口，不知道具体实现
//      回调函数中，调用者直接持有被调用者的函数引用

// 观察者模式的实现示例
#include <iostream>
#include <vector>
#include <algorithm>

// 观察者接口
class Observer
{
public:
    virtual ~Observer() = default;
    virtual void update(const std::string &message) = 0;
};

// 具体观察者
class ConcreteObserver : public Observer
{
private:
    std::string name;

public:
    ConcreteObserver(const std::string &n) : name(n) {}

    void update(const std::string &message) override
    {
        std::cout << name << " received: " << message << std::endl;
    }
};

// 主题（被观察者）
class Subject
{
private:
    std::vector<Observer *> observers;

public:
    void attach(Observer *observer)
    {
        observers.push_back(observer);
    }

    void detach(Observer *observer)
    {
        auto it = std::find(observers.begin(), observers.end(), observer);
        if (it != observers.end())
        {
            observers.erase(it);
        }
    }

    void notify(const std::string &message)
    {
        for (auto observer : observers)
        {
            observer->update(message);
        }
    }

    void createEvent(const std::string &message)
    {
        std::cout << "Event created: " << message << std::endl;
        notify(message);
    }
};

// 使用示例
int main()
{
    Subject subject;

    ConcreteObserver observer1("Observer 1");
    ConcreteObserver observer2("Observer 2");

    subject.attach(&observer1);
    subject.attach(&observer2);

    subject.createEvent("Important event!");

    subject.detach(&observer1);

    subject.createEvent("Another event!");

    return 0;
}

// 例子2 采集图片
#include <iostream>
#include <deque>
#include <vector>
#include <mutex>
#include <thread>
#include <chrono>
#include <condition_variable>
#include <atomic>

// 简单的图像类
class Image
{
private:
    int id;
    // 实际应用中这里会包含图像数据

public:
    Image(int id) : id(id) {}

    int getId() const { return id; }
};

// 观察者接口
class ImageObserver
{
public:
    virtual ~ImageObserver() = default;
    virtual void onImageAvailable(const Image &image) = 0;
};

// 图像队列管理器 - 被观察者
class ImageQueue
{
private:
    std::deque<Image> imageQueue;
    std::vector<ImageObserver *> observers;
    std::mutex queueMutex;
    std::condition_variable cv;

public:
    // 注册观察者
    void registerObserver(ImageObserver *observer)
    {
        observers.push_back(observer);
    }

    // 移除观察者
    void removeObserver(ImageObserver *observer)
    {
        auto it = std::find(observers.begin(), observers.end(), observer);
        if (it != observers.end())
        {
            observers.erase(it);
        }
    }

    // 添加图像到队列
    void pushImage(const Image &image)
    {
        {
            std::lock_guard<std::mutex> lock(queueMutex);
            imageQueue.push_back(image);
            std::cout << "图像 #" << image.getId() << " 已添加到队列，当前队列大小: " << imageQueue.size() << std::endl;
        }

        // 通知等待的线程
        cv.notify_one();

        // 如果队列大小大于1，通知所有观察者
        checkQueueAndNotify();
    }

    // 从队列获取图像
    bool getImage(Image &image)
    {
        std::unique_lock<std::mutex> lock(queueMutex);

        // 等待直到队列非空
        cv.wait(lock, [this]()
                { return !imageQueue.empty(); });

        if (imageQueue.empty())
        {
            return false;
        }

        image = imageQueue.front();
        imageQueue.pop_front();
        std::cout << "图像 #" << image.getId() << " 已从队列移除，当前队列大小: " << imageQueue.size() << std::endl;

        return true;
    }

    // 检查队列大小并在必要时通知观察者
    void checkQueueAndNotify()
    {
        std::lock_guard<std::mutex> lock(queueMutex);

        if (imageQueue.size() > 1)
        {
            // 获取队列前端的图像但不移除
            Image image = imageQueue.front();

            // 通知所有观察者
            for (auto observer : observers)
            {
                observer->onImageAvailable(image);
            }
        }
    }

    // 获取队列大小
    size_t size()
    {
        std::lock_guard<std::mutex> lock(queueMutex);
        return imageQueue.size();
    }
};

// 图像处理器 - 具体观察者
class ImageProcessor : public ImageObserver
{
private:
    ImageQueue &queue;
    std::atomic<bool> running{true};
    std::thread processingThread;

public:
    ImageProcessor(ImageQueue &q) : queue(q)
    {
        // 启动处理线程
        processingThread = std::thread(&ImageProcessor::processImages, this);
    }

    ~ImageProcessor()
    {
        running = false;
        if (processingThread.joinable())
        {
            processingThread.join();
        }
    }

    // 观察者接口实现
    void onImageAvailable(const Image &image) override
    {
        std::cout << "观察者通知: 图像 #" << image.getId() << " 可用于处理" << std::endl;
        // 在实际应用中，可能会在这里触发某些操作
        // 但在我们的设计中，处理线程会自动从队列获取图像
    }

private:
    // 图像处理线程
    void processImages()
    {
        while (running)
        {
            Image image(0);
            if (queue.getImage(image))
            {
                // 模拟图像处理
                std::cout << "处理图像 #" << image.getId() << std::endl;
                std::this_thread::sleep_for(std::chrono::milliseconds(50)); // 假设处理需要50ms
            }
        }
    }
};

// 相机采集类 - 生产者
class CameraCapture
{
private:
    ImageQueue &queue;
    std::atomic<bool> running{true};
    std::thread captureThread;
    int nextImageId = 1;

public:
    CameraCapture(ImageQueue &q) : queue(q)
    {
        // 启动采集线程
        captureThread = std::thread(&CameraCapture::captureImages, this);
    }

    ~CameraCapture()
    {
        running = false;
        if (captureThread.joinable())
        {
            captureThread.join();
        }
    }

private:
    // 图像采集线程
    void captureImages()
    {
        while (running)
        {
            // 模拟相机采集，每100ms一帧
            std::this_thread::sleep_for(std::chrono::milliseconds(100));

            // 创建新图像并添加到队列
            Image newImage(nextImageId++);
            std::cout << "采集图像 #" << newImage.getId() << std::endl;
            queue.pushImage(newImage);
        }
    }
};

// 主函数
int main()
{
    // 创建图像队列
    ImageQueue imageQueue;

    // 创建并注册图像处理器（观察者）
    ImageProcessor processor(imageQueue);
    imageQueue.registerObserver(&processor);

    // 创建相机采集器（生产者）
    CameraCapture camera(imageQueue);

    // 运行一段时间
    std::cout << "系统启动，将运行5秒..." << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(5));

    std::cout << "系统关闭" << std::endl;
    return 0;
}